﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SpiceNet.Circuits;
using SpiceNet.Diagnostics;

namespace SpiceNet.Simulations
{
    /// <summary>
    /// A job describing a noise analysis
    /// </summary>
    public class NoiseJob : Job
    {
        /// <summary>
        /// noise output summation node
        /// </summary>
        public string output;

        /// <summary>
        /// noise output reference node
        /// </summary>
        public string outputRef;

        /// <summary>
        /// name of the AC source used as input reference
        /// </summary>
        public string input;

        public double NstartFreq;
        public double NstopFreq;

        /// <summary>
        /// multiplier for decade/octave stepping,
        /// step for linear steps.
        /// </summary>
        public double NfreqDelta;

        /// <summary>
        /// frequency step at which we stopped last time
        /// </summary>
        public int NsavFstp;

        /// <summary>
        /// integrated output noise when we left off last time
        /// </summary>
        public double NsavOnoise;

        /// <summary>
        /// integrated input noise when we left off last time
        /// </summary>
        public double NsavInoise;

        /// <summary>
        /// values described below
        /// </summary>
        public Noise.StepTypes NstpType;

        public int NnumSteps;

        /// <summary>
        /// number of steps before we output a noise summary report
        /// </summary>
        public int NStpsSm;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="name"></param>
        public NoiseJob(string name)
            : base(name)
        {

        }

        /// <summary>
        /// Get or set the parameters of the noise job
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public override object this[string key]
        {
            get
            {
                switch (key)
                {
                    case "output": return output;
                    case "outputref": return outputRef;
                    case "input": return input;
                    case "dec": return (NstpType == Noise.StepTypes.DECADE);
                    case "oct": return (NstpType == Noise.StepTypes.OCTAVE);
                    case "lin": return (NstpType == Noise.StepTypes.LINEAR);
                    case "numsteps": return NnumSteps;
                    case "start": return NstartFreq;
                    case "stop": return NstopFreq;
                    case "ptspersum": return NStpsSm;
                }
                CircuitWarning.Warning(this, string.Format("Noise job {0}: Unrecognized parameter {1}", Name, key));
                return null;
            }
            set
            {
                switch (key)
                {
                    case "output": output = Convert.ToString(value); break;
                    case "outputref": outputRef = Convert.ToString(value); break;
                    case "input": input = Convert.ToString(value); break;
                    case "dec": NstpType = Noise.StepTypes.DECADE; break;
                    case "oct": NstpType = Noise.StepTypes.OCTAVE; break;
                    case "lin": NstpType = Noise.StepTypes.LINEAR; break;
                    case "numsteps": NnumSteps = Convert.ToInt32(value); break;
                    case "start": NstartFreq = Convert.ToDouble(value); break;
                    case "stop": NstopFreq = Convert.ToDouble(value); break;
                    case "ptspersum": NStpsSm = Convert.ToInt32(value); break;
                    default:
                        CircuitWarning.Warning(this, string.Format("Noise job {0}: Unrecognized parameter {1}", Name, key));
                        break;
                }

                // Perform check
                if (NstartFreq <= 0.0)
                {
                    CircuitWarning.Warning(this, string.Format("Noise job {0}: Frequency of 0 is invalid", Name));
                    NstartFreq = 1.0;
                }
                if (NstopFreq <= 0.0)
                {
                    CircuitWarning.Warning(this, string.Format("Noise job {0}: Frequency of 0 is invalid", Name));
                    NstopFreq = 1.0;
                }
            }
        }
    }
}
